package com.itheima.service.impl.common;

import com.itheima.common.ValidationEnum;
import com.itheima.utils.JwtUtil;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Author: Insight
 * @Description: TODO
 * @Date: 2024-06-03 10:40
 * @Version: 1.0
 */
@Service
public class ValidationServiceImpl implements com.itheima.service.IValidationService {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Value("${spring.mail.username}")
    private String from;
    @Autowired
    JavaMailSender javaMailSender;

    private static final long CODE_EXPIRE_TIME = 300; // 验证码过期时间，单位秒

    @Transactional
    @Override
    public void saveCode(String email, String code, Integer type) throws MessagingException {
        Date now = new Date();
        String redisKey = email + ":" + type;
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();

        if (operations.get(redisKey) != null) {
            throw new RuntimeException("当前您的验证码仍然有效，请不要重复发送");
        }
        HashMap<String, Object> claims = new HashMap<>();
        claims.put("email", email);
        claims.put("code", code);
        claims.put("type", type);
        String token = JwtUtil.genToken(claims);
        operations.set(redisKey, token, 300, TimeUnit.SECONDS);
        if (ValidationEnum.LOGIN.getCode().equals(type)) {
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom(from);
            message.setTo(email);
            message.setSentDate(now);
            message.setSubject("【程序员209】登录邮箱验证");
            message.setText("您本次的登录验证码是：" + code + "，有效期5分钟。请妥善保管，切勿泄露");
            javaMailSender.send(message);
        }else if(ValidationEnum.FORGET_PASS.getCode().equals(type)){
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper helper=new MimeMessageHelper(message);
            helper.setSubject("【程序员209】忘记密码验证");
            helper.setFrom(from);  // 发送人
            helper.setTo(email);
            helper.setSentDate(now);  // 富文本
            String context="<b>尊敬的用户：</b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;您好，您本次忘记密码的验证码是："+
                    "<b color=\"'red'\">"  + code + "</b><br>"
                    +"，有效期5分钟。请妥善保管，切勿泄露";
            helper.setText(context, true);
            javaMailSender.send(message);
        }else if(ValidationEnum.REGISTER.getCode().equals(type)){
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom(from);
            message.setTo(email);
            message.setSentDate(now);
            message.setSubject("【程序员209】用户注册邮箱验证");
            message.setText("您本次的用户注册验证码是：" + code + "，有效期5分钟。请妥善保管，切勿泄露");
            javaMailSender.send(message);
        }

    }

    @Override
    public void validateCode(String email, String code, Integer type) {
        String redisKey = email + ":" + type;
        ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
        String redisToken = operations.get(redisKey);
        System.out.println(redisToken+ "从redis中拉出来比对");
        if (redisToken == null) {
            throw new RuntimeException("验证码过期或错误，请重新获取");
        }

        Map<String, Object> claims = JwtUtil.parseToken(redisToken);
        if (!email.equals(claims.get("email")) || !code.equals(claims.get("code")) || !type.equals(claims.get("type"))) {
            throw new RuntimeException("验证码过期或错误，请重新获取");
        }
        operations.getOperations().delete(redisKey);
    }

}
